package cn.elwy.rcp.demo.service;

import java.util.LinkedList;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.viewers.TreeNode;

public class BuildManagerQueryService implements IBuildManagerQueryService {
  private static final IWorkspaceRoot workspace = ResourcesPlugin.getWorkspace().getRoot();

  @Override
  public List<TreeNode> listTreeNode() {
    List<TreeNode> nodes = new LinkedList<TreeNode>();
    listDBManagerScriptNode(nodes);
    listOtherNode(nodes);
    return nodes;
  }

  private void listDBManagerScriptNode(List<TreeNode> projects) {
    for (IProject project : workspace.getProjects()) {
      TreeNode node = getNodeFromProject(project);
      if (node != null) {
        projects.add(node);
      }
    }
  }

  private void listOtherNode(List<TreeNode> nodes) {

  }

  private TreeNode getNodeFromProject(IProject proj) {
    if (isDBScriptProject(proj)) {
      TreeNode project = new TreeNode(proj);
      project.setChildren(changeTreeNodes(getChildrenNode(proj)));
      return project;
    }
    return null;
  }

  private List<TreeNode> getChildrenNode(IProject proj) {
    List<TreeNode> nodes = new LinkedList<TreeNode>();
    try {
      getFolderAndFileNode(nodes, proj.members());
    } catch (CoreException e) {
      e.printStackTrace();
    }
    return nodes;
  }

  private void getFolderAndFileNode(List<TreeNode> nodes, IResource[] resources) throws CoreException {
    List<TreeNode> files = new LinkedList<TreeNode>();
    List<TreeNode> folders = new LinkedList<TreeNode>();

    for (IResource res : resources) {
      if (res instanceof IFolder) {
        IFolder folder = (IFolder) res;
        TreeNode folderNode = new TreeNode(folder);
        folders.add(folderNode);
        List<TreeNode> folderNodes = new LinkedList<TreeNode>();
        getFolderAndFileNode(folderNodes, folder.members());
        folderNode.setChildren(changeTreeNodes(folderNodes));
      }
      if (res instanceof IFile) {
        IFile file = (IFile) res;
        if (!file.getName().startsWith(".")) {
          TreeNode fileNode = new TreeNode(file);
          files.add(fileNode);
        }
      }
    }
    nodes.addAll(folders);
    nodes.addAll(files);
  }

  public static boolean isDBScriptProject(IProject project) {
    if (project == null) {
      throw new IllegalArgumentException("Cannot check nature of null project!"); //$NON-NLS-1$
    }
    try {
      if (!project.exists()) {
        return false;
      }
      return project.getNature("cn.elwy.rcp.builder.dbscript.DBScriptProject") != null;
    } catch (CoreException e) {
      e.printStackTrace();
    }
    return false;
  }

  private TreeNode[] changeTreeNodes(List<TreeNode> listTreeNode) {
    TreeNode[] nodes = new TreeNode[listTreeNode.size()];
    for (int i = 0; i < listTreeNode.size(); i++) {
      nodes[i] = listTreeNode.get(i);
    }
    return nodes;
  }
}
